
package my.algorithms.mcorrea;

/**
 *
 * @author mcorrea
 */
public class SpiralMatrix {
	
	
	public static void main(String args[]){
		
		int matrix[][] =  new int[1][1];
		matrix[0][0] = 1;
		System.out.println("--------------1x1--------------");
		printMatrix(matrix);
		System.out.println("index spiral");
		printSpiralMatrixIndex(matrix, 1, 1, 0, 0);
		System.out.println("content spiral");
		printSpiralMatrixContent(matrix, 1, 1, 0, 0);
		System.out.println();
		
		int matrix10[][] =  {{1,2}};
		System.out.println("--------------1x2--------------");
		printMatrix(matrix10);
		System.out.println("index spiral");
		printSpiralMatrixIndex(matrix10, 1, 2, 1, 0);
		System.out.println("content spiral");
		printSpiralMatrixContent(matrix10, 1, 2, 1, 0);
		System.out.println();
		 
		int matrix11[][] =  {{1}, {2}};
		System.out.println("--------------2x1--------------");
		printMatrix(matrix11);
		System.out.println("index spiral");
		printSpiralMatrixIndex(matrix11, 2, 1, 0, 0);
		System.out.println("content spiral");
		printSpiralMatrixContent(matrix11, 2, 1, 0, 0);
		System.out.println();
		
		
		int matrix2[][] = { {1,2}, {3,4} };
		System.out.println("------------2x2----------------");
		printMatrix(matrix2);
		System.out.println("index spiral");
		printSpiralMatrixIndex(matrix2, 2, 2, 1, 0);
		System.out.println("content spiral");
		printSpiralMatrixContent(matrix2, 2, 2, 1, 0);
		System.out.println();
		
		int matrix3[][] = { {1,2,3,4}, {5,6,7,8}, {9, 10, 11, 12}, {13, 14, 15, 16}};
		System.out.println("------------nxm, n==m----------------");
		printMatrix(matrix3);
		System.out.println("index spiral");
		printSpiralMatrixIndex(matrix3, 4, 4,  3, 0);
		System.out.println("content spiral");
		printSpiralMatrixContent(matrix3, 4, 4,  3, 0);
		System.out.println();
	
		int matrix4[][] =  { {1,2,3,4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}, {17, 18, 19, 20} };	
		System.out.println("------------nxm, n!=m n>m----------------");
		printMatrix(matrix4);
		System.out.println("index spiral");
		printSpiralMatrixIndex(matrix4, 5, 4, 3, 0);
		System.out.println("content spiral");
		printSpiralMatrixContent(matrix4, 5, 4, 3, 0);
		System.out.println();

		int matrix5[][] =  { {1,2,3,4}, {5, 6, 7, 8}, {9, 10, 11, 12} };
		System.out.println("------------nxm, m>n----------------");
		printMatrix(matrix5);
		System.out.println("index spiral");
		printSpiralMatrixIndex(matrix5, 3, 4, 3, 0);
		System.out.println("content spiral");
		printSpiralMatrixContent(matrix5, 3, 4, 3, 0);
		System.out.println();
	
		int matrix6[][] =  { {1,2,3}, {4,5,6}, {7,8,9},{10, 11, 12} };
		System.out.println("------------nxm, one two left----------------");
		printMatrix(matrix6);
		System.out.println("index spiral");
		printSpiralMatrixIndex(matrix6, 4, 3, 2, 0);
		System.out.println("content spiral");
		printSpiralMatrixContent(matrix6, 4, 3, 2, 0);
		System.out.println();
		
		int matrix7[][] =  { {1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}, {11, 12, 13, 14, 15},{16, 17 , 18, 19, 20},{21, 22, 23, 24, 25} };
		System.out.println("------------nxm, one element left----------------");
		printMatrix(matrix7);
		System.out.println("index spiral");
		printSpiralMatrixIndex(matrix7, 5, 5, 4, 0);
		System.out.println("content spiral");
		printSpiralMatrixContent(matrix7, 5, 5, 4, 0);
		System.out.println();
		
		//exercise test
		//test nxm matrix n=m but uneven
		int matrix8[][] =  { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12},{13, 14, 15, 16} };
		System.out.println("------------Exercise!----------------");
		printMatrixPositions(matrix8);
		printSpiralMatrixContent(matrix8, 4, 4, 3, 0);
		System.out.println();
		
		//exercise test
		//test nxm matrix n=m but uneven
		int matrix9[][] =  { {1, 2, 3, 4, 5, 6}, {7, 8, 9, 10, 11, 12}, {13, 14, 15, 16, 17, 18} };
		System.out.println("------------Exercise 2!----------------");
		printMatrixPositions(matrix9);
		printSpiralMatrixContent(matrix9, 3, 6, 5, 0);
		
			
	}
	
	/**
	 * Print Indexes in Spiral
	 * @param matrix
	 * @param n
	 * @param m
	 * @param startColumn
	 * @param startRow 
	 * The algorithm runs in O(nm) 
	 */
	public static void printSpiralMatrixIndex(int matrix[][], int n, int m, int startColumn, int startRow){
		
		if(n <= 0 || m <=0) return;
		
		//rows printing --> 
		//from startRow which holds 0, 1, 2,... count the columsn as well 
		//--the variable is used because its value not becuase its meeaning 
		for (int j = startRow; j <= startColumn; j++) {
			System.out.print(startRow+","+j + " ");
		}
 
		System.out.println();	
		
		//column printing down
		// from startRow+1 (aboid printing the value was printing before), till n-startRow-1 which the last row in the series
		for (int i = startRow+1; i <= n+startRow-1; i++) {
			System.out.print(i+","+startColumn + " ");
		}
		
		System.out.println();	
		//rows printing <-- 
		//from the startColumn-1 (avoid printing before) till the first column startColumn-m+1
		// and the rows must be greater than one. otherwise already printed in last step
		for (int j = startColumn-1;  j >= startColumn - m + 1 && n>1; j--  ) {
			System.out.print( n+startRow-1+","+j + " " );
		}
		
		System.out.println();	
		//columns printing up
		// from the lastRow not being printed yet (-2) till the startRow
		for (int i = n+startRow-2; i > startRow; i-- ) { 
			System.out.print(i+","+ (startColumn - m + 1)  + " ");
		}
		System.out.println();	
		printSpiralMatrixIndex(matrix, n-2, m-2, startColumn-1, startRow+1 );
		
	
	}
	
	/**
	 * PRint the content in Spiral fashion
	 * @param matrix
	 * @param n
	 * @param m
	 * @param startColumn
	 * @param startRow 
	 */
	public static void printSpiralMatrixContent(int matrix[][], int n, int m, int startColumn, int startRow){
		
		if(n <= 0 || m <=0) return;
		
		//rows printing --> 
		//from startRow which holds 0, 1, 2,... count the columsn as well 
		//--the variable is used because its value not becuase its meeaning
		for (int j = startRow; j <= startColumn; j++) {
			System.out.print(matrix[startRow][j] + " ");
		}

		//rows printing <-- 
		//from the startColumn-1 (avoid printing before) till the first column startColumn-m+1
		// and the rows must be greater than one. otherwise already printed in last step
		for (int i = startRow+1; i <= n+startRow-1; i++) {
			System.out.print(matrix[i][startColumn] + " ");
		}
		
		
		//rows printing <-- 
		//from the startColumn-1 (avoid printing before) till the first column startColumn-m+1
		// and the rows must be greater than one. otherwise already printed in last step
		for (int j = startColumn-1;  j >= startColumn - m + 1 && n>1; j--  ) {
			System.out.print(matrix[n+startRow-1][j] + " " );
		}
		
			
		//columns printing up
		// from the lastRow not being printed yet (-2) till the startRow
		for (int i = n+startRow-2; i > startRow; i-- ) { 
			System.out.print( matrix[i][(startColumn - m + 1)]  + " ");
		}
			
		printSpiralMatrixContent(matrix, n-2, m-2, startColumn-1, startRow+1 );
		
	
	}
	
	
	
	public static void printMatrixPositions(int matrix[][]){
		for(int i=0; i< matrix.length; i++){
			for(int j=0; j<matrix[i].length; j++){
				System.out.print(i+","+j+"  ");
			}
			System.out.println();
		}
	
	}
	
	
	
	public static void printMatrix(int matrix[][]){
		for(int i=0; i< matrix.length; i++){
			for(int j=0; j<matrix[i].length; j++){
				System.out.print(matrix[i][j]+"   ");
			}
			System.out.println();
		}
	
	}
	
}
